package com.bndg.dnttapwhite

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.Log
import android.view.MotionEvent
import android.view.SurfaceHolder
import android.view.SurfaceView

// 新增接口
interface OnGameOverListener {
    fun onGameOver(score: Int)
}

// 游戏线程类，继承自 Thread
class GameThread(private val surfaceHolder: SurfaceHolder, private val gameView: GameSurfaceView) :
    Thread() {

    // 线程运行标志
    private var running = false

    /**
     * 设置线程运行状态
     */
    fun setRunning(run: Boolean) {
        running = run
    }

    /**
     * 线程运行方法，不断更新和绘制游戏界面
     */
    override fun run() {
        var canvas: Canvas? = null
        while (running) {
            try {
                // 锁定画布
                canvas = surfaceHolder.lockCanvas()
                synchronized(surfaceHolder) {
                    // 更新游戏状态
                    gameView.update()
                    // 绘制游戏界面
                    gameView.draw(canvas)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                canvas?.let {
                    // 解锁画布并提交绘制结果
                    surfaceHolder.unlockCanvasAndPost(it)
                }
            }
        }
    }
}

// 游戏的 SurfaceView 类，继承自 SurfaceView 并实现 SurfaceHolder.Callback 接口
class GameSurfaceView(context: Context) : SurfaceView(context), SurfaceHolder.Callback {

    private val soundPlayer: SoundPlayer? = SoundPlayer(context)
    private var downSpeed = 8

    // 游戏线程
    private lateinit var thread: GameThread

    // 每个方块的大小
    private var blockWidth = 200f
    private var blockHeight = 200 * 1.5f

    // 每列的行数
    private var rows = 5

    // 列数
    private val cols = 4

    // 存储所有方块的列表
    private val blocks = mutableListOf<Block>()

    // 玩家得分
    private var score = 0

    // 游戏是否正在运行的标志
    private var isRunning = false

    // 游戏是否结束的标志
    private var gameOver = false

    // 背景画
    val paintBg = Paint()

    // 创建两个 Paint 对象
    val fillPaint = Paint()   // 用于填充矩形内部
    val borderPaint = Paint() // 用于绘制矩形边框
    val paintScore = Paint()

    // 新增成员变量
    private var gameOverListener: OnGameOverListener? = null

    init {
        // 为 SurfaceHolder 添加回调
        holder.addCallback(this)
        paintBg.color = Color.YELLOW

        // 设置填充 Paint 的颜色为黑色
        fillPaint.color = Color.BLACK
        fillPaint.style = Paint.Style.FILL  // 填充矩形内部

        // 设置边框 Paint 的颜色为灰色
        borderPaint.color = Color.DKGRAY
        borderPaint.strokeWidth = 1f  // 设置边框宽度
        borderPaint.style = Paint.Style.STROKE  // 只绘制边框，不填充

        // 绘制得分信息
        paintScore.color = Color.RED
        paintScore.textSize = 50f
    }

    // 设置游戏结束监听器
    fun setOnGameOverListener(listener: OnGameOverListener) {
        this.gameOverListener = listener
    }

    /**
     * 初始化方块，在游戏开始时创建初始的方块布局
     */
    private fun initializeBlocks() {
        blocks.clear()
        // 4列均分宽度
        blockWidth = (width / cols).toFloat()
        // 5行均分高度
        blockHeight = (height / rows).toFloat()
        Log.d(">>>>", "initializeBlocks: $blockWidth $blockHeight")
        for (row in 0 until rows) {
            // 在每一行随机选择一个黑色方块的列索引
            val blackCol = (0 until cols).random()

            for (col in 0 until cols) {
                // 计算方块的 x 和 y 坐标
                val x = col * blockWidth
                val y = row * blockHeight

                // 判断当前列是否为黑色列
                val isBlack = col == blackCol

                // 将方块添加到列表中
                blocks.add(Block(x, y, blockWidth, blockHeight, isBlack))
//                Log.d(">>>>", "draw: col=$col row=$row isBlack=$isBlack")
            }
        }
        // 顶部额外添加一行
        addNewRow()
    }

    /**
     * 当 Surface 被创建时调用，启动游戏线程
     */
    override fun surfaceCreated(holder: SurfaceHolder) {
        initializeBlocks() // 初始化方块
        val lockCanvas = holder.lockCanvas()
        draw(lockCanvas)
        holder.unlockCanvasAndPost(lockCanvas)
    }

    /**
     * 当 Surface 的格式或大小发生变化时调用，此处为空实现
     */
    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}

    /**
     * 当 Surface 被销毁时调用，停止游戏线程
     */
    override fun surfaceDestroyed(holder: SurfaceHolder) {
        var retry = true
        // 设置线程运行标志为 false
        isRunning = false
        thread.setRunning(isRunning)
        while (retry) {
            try {
                // 等待线程结束
                thread.join()
                retry = false
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }
        }
    }

    /**
     * 处理触摸事件，判断玩家是否点击到黑色方块
     */
    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_DOWN) {
            if (gameOver) {
                restartGame()
            } else {
                // 计算点击的方块列和行
                for (block in blocks) {
                    if (block.isClickInside(event.x, event.y)) {
                        if (block.isBlack) {
                            // 点击到黑色方块，得分加 1
                            score++
                            soundPlayer?.playNote()
                            // 将黑色方块变为灰色
                            block.isGray = true
                            Log.d(">>>>", "点击到黑色方块，得分加 1，当前得分：$score")
                            if (!isRunning) {
                                isRunning = true
                                if (!::thread.isInitialized || !thread.isAlive) {
                                    thread = GameThread(holder, this)
                                    thread.setRunning(isRunning)
                                    thread.start()
                                }
                            }
                        } else {
                            // 点击到白色方块，游戏结束
                            gameOver = true
                            isRunning = false
                            if (::thread.isInitialized && thread.isAlive) {
                                thread.setRunning(isRunning) // 游戏结束后暂停游戏线程
                            }
                            Log.d(">>>>", "点击到白色方块，游戏结束，当前得分：$score")
                            // 调用监听器的方法
                            gameOverListener?.onGameOver(score)
                        }
                        break
                    }
                }
            }
            return true
        }
        return false
    }

    fun resumeGame() {
        if (!::thread.isInitialized || !thread.isAlive) {
            // 如果 thread 没有被初始化或已经停止，则重新创建线程
            if (!gameOver) {
                isRunning = true
                thread = GameThread(holder, this)
                thread.setRunning(isRunning)
                thread.start()
            }
        }
    }

    fun pauseGame() {
        if (::thread.isInitialized && thread.isAlive) {
            isRunning = false
            thread.setRunning(isRunning)
            var retry = true
            while (retry) {
                try {
                    thread.join()
                    retry = false
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }
        }
    }

    /**
     * 添加新的一行方块
     */
    private fun addNewRow() {
        val topBlockY: Float = (blocks.minByOrNull { it.y }?.y ?: 0) as Float
        downSpeed += 2
        if (downSpeed > 30) {
            downSpeed = 30
        }
        val newCol = (0..cols - 1).random()
        for (col in 0 until cols) {
            val isBlack = (col == newCol)
            // 在屏幕上方添加新的方块
            val element = Block(
                col * blockWidth,
                topBlockY - blockHeight,
                blockWidth,
                topBlockY + blockHeight,
                isBlack
            )
            blocks.add(element)
            Log.d(">>>>", "addNewRow: ${element.x} ${element.y} ${element.height}")

        }
    }

    /**
     * 更新游戏状态，控制方块下落速度
     */
    fun update() {
        if (blocks.isEmpty()) {
            return
        }
        if (!gameOver) {
            for (block in blocks) {
                // 记录上一帧的位置
                // 方块下落速度
                block.y += downSpeed
            }

            // 判断最底部方块是否超出屏幕底部
            val bottomBlockY: Float = (blocks.maxByOrNull { it.y }?.y ?: 0) as Float
            if (bottomBlockY > height) {
                // 检查超出屏幕底部的黑色方块是否被点击
                val bottomBlackBlocks = blocks.filter { it.y > height && it.isBlack }
                for (block in bottomBlackBlocks) {
                    if (!block.isGray) {
                        gameOver = true
                        isRunning = false
                        thread.setRunning(isRunning) // 游戏结束后暂停游戏线程
                        Log.d(">>>>", "黑色方块未被点击，游戏结束，当前得分：$score")
                        // 调用监听器的方法
                        gameOverListener?.onGameOver(score)
                        break
                    }
                }

                // 如果游戏未结束，新增一行方块并移除超出屏幕底部的方块
                if (!gameOver) {
                    addNewRow()
                    blocks.removeAll { it.y > height }
                }
            }

        }
    }

    var count = 1

    /**
     * 绘制游戏界面，包括方块和得分信息
     */
    override fun draw(canvas: Canvas) {
        super.draw(canvas)
        canvas ?: return
        // 绘制白色背景
        canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paintBg)
        // 先绘制矩形内部
        // 绘制方块
        count++
        for (i in 0 until blocks.size) {
            val block = blocks[i]
            if (block.isGray) {
                fillPaint.color = Color.GRAY
            } else if (block.isBlack) {
                fillPaint.color = Color.BLACK
            } else {
                fillPaint.color = Color.WHITE
            }
            // 绘制从上次位置到当前位置之间的区域 y值跨越大了有空隙？
            val endY = block.y + block.height
            val rect = RectF(block.x, block.y, block.x + block.width, endY)
            canvas.drawRect(rect, fillPaint)
            // 再绘制矩形的边框
            canvas.drawRect(rect, borderPaint)
            if (count % 40 == 0 && i > 15) {
                Log.d(">>>>", "draw: $rect ${block.isBlack}")
            }
        }

        canvas.drawText("Score: $score", 50f, 100f, paintScore)
    }

    // 方块数据类，存储方块的位置、大小和颜色信息
    data class Block(
        var x: Float,
        var y: Float,
        val width: Float,
        val height: Float,
        var isBlack: Boolean
    ) {
        var isGray: Boolean = false

        // 判断点击坐标是否在方块内
        fun isClickInside(clickX: Float, clickY: Float): Boolean {
            return clickX >= x && clickX <= (x + width) && clickY >= y && clickY <= (y + height)
        }
    }

    /**
     * 重新开始游戏
     */
    fun restartGame() {
        gameOver = false
        score = 0
        downSpeed = 8
        blocks.clear()
        initializeBlocks()
        val lockCanvas = holder.lockCanvas()
        draw(lockCanvas)
        holder.unlockCanvasAndPost(lockCanvas)
    }

    fun release() {
        soundPlayer?.release()
    }
}